package de.bazinga.rotw.objects;

import java.net.URL;

import com.jme.bounding.BoundingBox;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Box;
import com.jmex.game.state.GameStateManager;
import com.jmex.jbullet.PhysicsSpace;
import com.jmex.jbullet.collision.shapes.CollisionShape;
import com.jmex.jbullet.nodes.PhysicsNode;

import de.bazinga.rotw.collision.CollidableObjects;
import de.bazinga.rotw.game.RotwGameState;
import de.bazinga.rotw.network.BasicSyncManager;
import de.bazinga.rotw.network.Client;
import de.bazinga.rotw.network.Server;
import de.bazinga.rotw.network.message.ItemMessage;
import de.bazinga.rotw.person.Person;
import de.bazinga.rotw.texture.TextureCache;

public class Button extends Node implements GameObject {
	private static final long serialVersionUID = 1L;

	
	protected Box button = null;
	
	private PhysicsNode wallPhysicsNode = null;
	protected Box wall = null;
	
	protected long openDuration = 0;
	protected long lastTimeHidden = 0;
	
	protected boolean hideOnCollision = false;
	
	protected int team = 0;

	/**
	 * In XML-Datei einbauen
	 * @param buttonMin
	 * @param buttonMax
	 * @param wallMin
	 * @param wallMax
	 * @param openDuration
	 */
	public Button(Vector3f buttonMin, Vector3f buttonMax, Vector3f wallMin, Vector3f wallMax, long openDuration, boolean hideOnCollision, int team, URL buttonTexture, URL wallTexture) {
		this.openDuration = openDuration;
		this.hideOnCollision = hideOnCollision;
		this.team = team;
		
		button = new Box("button", buttonMin, buttonMax);
		
		button.setLightCombineMode(Spatial.LightCombineMode.Off);
		
		button.setModelBound(new BoundingBox());
		button.updateModelBound();
		
		if(buttonTexture != null) {
			button.setRenderState(TextureCache.getInstance().getTexture(buttonTexture));
		}
		button.updateRenderState();
		
		this.attachChild(button);
		
		
		
		
		Vector3f extend = wallMax.subtract(wallMin).mult(0.5f);
		
		wall = new Box("wall",Vector3f.ZERO,extend.x, extend.y, extend.z);
		
		wall.setLightCombineMode(Spatial.LightCombineMode.Off);
		
		
		if(!hideOnCollision) {
			wall.setCullHint(CullHint.Always);
			wall.setIsCollidable(false);
		}
		
		
		wall.setModelBound(new BoundingBox());
		wall.updateModelBound();
		
		if(wallTexture != null) {
			wall.setRenderState(TextureCache.getInstance().getTexture(wallTexture));
		}
		wall.updateRenderState();
		
		
		wallPhysicsNode = new PhysicsNode(wall,CollisionShape.ShapeTypes.BOX,0);
        wallPhysicsNode.setLocalTranslation(wallMin.add(extend));
        
		CollidableObjects.getInstance().addObject("wall",wallPhysicsNode);
		((Node)CollidableObjects.getInstance().getObjects("wallNode").get(0)).attachChild(wallPhysicsNode);
       
        
        wallPhysicsNode.updateRenderState();
		// Add ground to physicsNode
        //((RotwGameState)GameStateManager.getInstance().getChild("gameState")).getPhyicsSpace().add(groundPhysicsNode);
		if(hideOnCollision)
			PhysicsSpace.getPhysicsSpace().add(wallPhysicsNode);
		//PhysicsSpace.getPhysicsSpace().
	}
	
	public void hide() {
		if(hideOnCollision) {
			wall.setCullHint(CullHint.Always);
			wall.setIsCollidable(false);
			PhysicsSpace.getPhysicsSpace().remove(wallPhysicsNode);
		}else{
			wall.setCullHint(CullHint.Never);
			wall.setIsCollidable(true);
			PhysicsSpace.getPhysicsSpace().add(wallPhysicsNode);
		}
		lastTimeHidden = System.currentTimeMillis();
		((RotwGameState)GameStateManager.getInstance().getChild("gameState")).addItemToRespawn(this);
	}

	public void onCollision(Person person, boolean sendMessage) {
		if(team == 1 && person.getTeam() == Person.TEAM_TWO) return ;
		if(team == 2 && person.getTeam() == Person.TEAM_ONE) return ;
		
		if(person.hasCollision(button, false)) {
			// Tell Server that we updated
			if(sendMessage) {
				ItemMessage itemMsg = new ItemMessage();
				itemMsg.setItem(ItemMessage.ITEM_BUTTON);
				itemMsg.setItemIndex(CollidableObjects.getInstance().getObjects("gameObjects").indexOf(this));
				itemMsg.setHide(true);
				
				BasicSyncManager syncManager = 
					((RotwGameState)GameStateManager.getInstance().getChild("gameState")).getSyncManager();
				if(syncManager instanceof Client) {
					((Client) syncManager).getClient().sendToServer(itemMsg);
				}else{
					((Server) syncManager).getServer().sendToAll(itemMsg);
				}
			}
			hide();
		}
	}

	
	public boolean respawn() {
		if( (System.currentTimeMillis() - lastTimeHidden) > openDuration) {
			if(hideOnCollision) {
				wall.setCullHint(CullHint.Never);
				wall.setIsCollidable(true);
			}else{
				wall.setCullHint(CullHint.Always);
				wall.setIsCollidable(false);
			}
			
			return true;
		}
		return false;
	}

}
